package com.cencat.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cencat.order.dto.RouteInvoiceDTO;
import com.cencat.order.entity.RouteInvoice;
import com.cencat.order.mapper.RouteInvoiceMapper;
import com.cencat.order.service.RouteInvoiceService;
import com.cencat.order.vo.RouteInvoiceVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 线路发票业务逻辑实现类
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RouteInvoiceServiceImpl extends ServiceImpl<RouteInvoiceMapper, RouteInvoice> implements RouteInvoiceService {

    private final RouteInvoiceMapper routeInvoiceMapper;

    @Override
    public IPage<RouteInvoiceVO> getRouteInvoicePage(Page<RouteInvoiceVO> page, String invoiceNumber,
                                                   Long routeId, Long merchantId, Integer invoiceStatus,
                                                   Integer auditStatus, Integer paymentStatus,
                                                   String invoiceType, LocalDateTime startTime,
                                                   LocalDateTime endTime) {
        log.info("分页查询线路发票列表，参数：invoiceNumber={}, routeId={}, merchantId={}, invoiceStatus={}, auditStatus={}, paymentStatus={}, invoiceType={}, startTime={}, endTime={}",
                invoiceNumber, routeId, merchantId, invoiceStatus, auditStatus, paymentStatus, invoiceType, startTime, endTime);
        
        IPage<RouteInvoiceVO> result = routeInvoiceMapper.selectRouteInvoicePage(page, invoiceNumber, routeId,
                merchantId, invoiceStatus, auditStatus, paymentStatus, invoiceType, startTime, endTime);
        
        log.info("分页查询线路发票列表完成，总数：{}", result.getTotal());
        return result;
    }

    @Override
    public RouteInvoiceVO getByInvoiceNumber(String invoiceNumber) {
        log.info("根据发票号码查询发票信息，invoiceNumber={}", invoiceNumber);
        
        if (!StringUtils.hasText(invoiceNumber)) {
            log.warn("发票号码不能为空");
            return null;
        }
        
        RouteInvoiceVO result = routeInvoiceMapper.selectByInvoiceNumber(invoiceNumber);
        log.info("根据发票号码查询发票信息完成，result={}", result != null ? "找到" : "未找到");
        return result;
    }

    @Override
    public List<RouteInvoiceVO> getByRouteId(Long routeId, Integer invoiceStatus, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("根据路线ID查询发票列表，routeId={}, invoiceStatus={}, startTime={}, endTime={}",
                routeId, invoiceStatus, startTime, endTime);
        
        if (routeId == null) {
            log.warn("路线ID不能为空");
            return List.of();
        }
        
        List<RouteInvoiceVO> result = routeInvoiceMapper.selectByRouteId(routeId, invoiceStatus, startTime, endTime);
        log.info("根据路线ID查询发票列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public List<RouteInvoiceVO> getByMerchantId(Long merchantId, Integer invoiceStatus, LocalDateTime startTime, LocalDateTime endTime) {
        log.info("根据商家ID查询发票列表，merchantId={}, invoiceStatus={}, startTime={}, endTime={}",
                merchantId, invoiceStatus, startTime, endTime);
        
        if (merchantId == null) {
            log.warn("商家ID不能为空");
            return List.of();
        }
        
        List<RouteInvoiceVO> result = routeInvoiceMapper.selectByMerchantId(merchantId, invoiceStatus, startTime, endTime);
        log.info("根据商家ID查询发票列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public List<RouteInvoiceVO> getByStatus(Integer invoiceStatus, Integer auditStatus, Integer paymentStatus,
                                          LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        log.info("根据状态查询发票列表，invoiceStatus={}, auditStatus={}, paymentStatus={}, startTime={}, endTime={}, limit={}",
                invoiceStatus, auditStatus, paymentStatus, startTime, endTime, limit);
        
        List<RouteInvoiceVO> result = routeInvoiceMapper.selectByStatus(invoiceStatus, auditStatus, paymentStatus,
                startTime, endTime, limit);
        log.info("根据状态查询发票列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public List<RouteInvoiceVO> getByInvoiceType(String invoiceType, Integer invoiceStatus,
                                               LocalDateTime startTime, LocalDateTime endTime, Integer limit) {
        log.info("根据发票类型查询发票列表，invoiceType={}, invoiceStatus={}, startTime={}, endTime={}, limit={}",
                invoiceType, invoiceStatus, startTime, endTime, limit);
        
        if (!StringUtils.hasText(invoiceType)) {
            log.warn("发票类型不能为空");
            return List.of();
        }
        
        List<RouteInvoiceVO> result = routeInvoiceMapper.selectByInvoiceType(invoiceType, invoiceStatus,
                startTime, endTime, limit);
        log.info("根据发票类型查询发票列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public List<RouteInvoiceVO> getByAmountRange(BigDecimal minAmount, BigDecimal maxAmount,
                                               Integer invoiceStatus, LocalDateTime startTime,
                                               LocalDateTime endTime, Integer limit) {
        log.info("根据金额范围查询发票列表，minAmount={}, maxAmount={}, invoiceStatus={}, startTime={}, endTime={}, limit={}",
                minAmount, maxAmount, invoiceStatus, startTime, endTime, limit);
        
        List<RouteInvoiceVO> result = routeInvoiceMapper.selectByAmountRange(minAmount, maxAmount, invoiceStatus,
                startTime, endTime, limit);
        log.info("根据金额范围查询发票列表完成，数量：{}", result.size());
        return result;
    }

    @Override
    public Map<String, Object> getRouteInvoiceStatistics(Long routeId, Long merchantId, Integer invoiceStatus,
                                                        Integer auditStatus, Integer paymentStatus,
                                                        String invoiceType, LocalDateTime startTime,
                                                        LocalDateTime endTime) {
        log.info("查询线路发票统计信息，routeId={}, merchantId={}, invoiceStatus={}, auditStatus={}, paymentStatus={}, invoiceType={}, startTime={}, endTime={}",
                routeId, merchantId, invoiceStatus, auditStatus, paymentStatus, invoiceType, startTime, endTime);
        
        Map<String, Object> result = routeInvoiceMapper.selectRouteInvoiceStatistics(routeId, merchantId,
                invoiceStatus, auditStatus, paymentStatus, invoiceType, startTime, endTime);
        
        log.info("查询线路发票统计信息完成");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createRouteInvoice(RouteInvoiceDTO routeInvoiceDTO) {
        log.info("创建线路发票，routeInvoiceDTO={}", routeInvoiceDTO);
        
        if (routeInvoiceDTO == null) {
            log.warn("发票信息不能为空");
            return false;
        }
        
        // 检查发票号码是否已存在
        if (StringUtils.hasText(routeInvoiceDTO.getInvoiceNumber())) {
            RouteInvoiceVO existingInvoice = routeInvoiceMapper.selectByInvoiceNumber(routeInvoiceDTO.getInvoiceNumber());
            if (existingInvoice != null) {
                log.warn("发票号码已存在：{}", routeInvoiceDTO.getInvoiceNumber());
                return false;
            }
        }
        
        RouteInvoice routeInvoice = new RouteInvoice();
        BeanUtils.copyProperties(routeInvoiceDTO, routeInvoice);
        routeInvoice.setCreateTime(LocalDateTime.now());
        routeInvoice.setUpdateTime(LocalDateTime.now());
        routeInvoice.setDeleted(false);
        
        boolean result = save(routeInvoice);
        log.info("创建线路发票完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRouteInvoice(Long invoiceId, RouteInvoiceDTO routeInvoiceDTO) {
        log.info("更新线路发票，invoiceId={}, routeInvoiceDTO={}", invoiceId, routeInvoiceDTO);
        
        if (invoiceId == null || routeInvoiceDTO == null) {
            log.warn("发票ID和发票信息不能为空");
            return false;
        }
        
        RouteInvoice existingInvoice = getById(invoiceId);
        if (existingInvoice == null) {
            log.warn("发票不存在：{}", invoiceId);
            return false;
        }
        
        RouteInvoice routeInvoice = new RouteInvoice();
        BeanUtils.copyProperties(routeInvoiceDTO, routeInvoice);
        routeInvoice.setId(invoiceId);
        routeInvoice.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(routeInvoice);
        log.info("更新线路发票完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean generateInvoiceAutomatically(Long routeId, Map<String, Object> generationRules) {
        log.info("自动生成发票，routeId={}, generationRules={}", routeId, generationRules);
        
        if (routeId == null) {
            log.warn("路线ID不能为空");
            return false;
        }
        
        // 这里应该实现实际的自动发票生成逻辑
        // 根据路线信息和生成规则创建发票
        
        boolean result = routeInvoiceMapper.generateInvoiceAutomatically(routeId, generationRules) > 0;
        log.info("自动生成发票完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchGenerateInvoices(List<Long> routeIds, Map<String, Object> generationRules) {
        log.info("批量生成发票，routeIds={}, generationRules={}", routeIds, generationRules);
        
        if (routeIds == null || routeIds.isEmpty()) {
            log.warn("路线ID列表不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.batchGenerateInvoices(routeIds, generationRules) > 0;
        log.info("批量生成发票完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceStatus(Long invoiceId, Integer invoiceStatus, String statusRemark) {
        log.info("更新发票状态，invoiceId={}, invoiceStatus={}, statusRemark={}",
                invoiceId, invoiceStatus, statusRemark);
        
        if (invoiceId == null || invoiceStatus == null) {
            log.warn("发票ID和状态不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.updateInvoiceStatus(invoiceId, invoiceStatus, statusRemark) > 0;
        log.info("更新发票状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAuditStatus(Long invoiceId, Integer auditStatus, String auditRemark,
                                    LocalDateTime auditTime, Long auditorId) {
        log.info("更新审核状态，invoiceId={}, auditStatus={}, auditRemark={}, auditTime={}, auditorId={}",
                invoiceId, auditStatus, auditRemark, auditTime, auditorId);
        
        if (invoiceId == null || auditStatus == null) {
            log.warn("发票ID和审核状态不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.updateAuditStatus(invoiceId, auditStatus, auditRemark,
                auditTime, auditorId) > 0;
        log.info("更新审核状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePaymentStatus(Long invoiceId, Integer paymentStatus, String paymentMethod,
                                      LocalDateTime paymentTime, String transactionId) {
        log.info("更新支付状态，invoiceId={}, paymentStatus={}, paymentMethod={}, paymentTime={}, transactionId={}",
                invoiceId, paymentStatus, paymentMethod, paymentTime, transactionId);
        
        if (invoiceId == null || paymentStatus == null) {
            log.warn("发票ID和支付状态不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.updatePaymentStatus(invoiceId, paymentStatus, paymentMethod,
                paymentTime, transactionId) > 0;
        log.info("更新支付状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAmountInfo(Long invoiceId, BigDecimal totalAmount, BigDecimal taxAmount,
                                   BigDecimal netAmount, String amountRemark) {
        log.info("更新金额信息，invoiceId={}, totalAmount={}, taxAmount={}, netAmount={}, amountRemark={}",
                invoiceId, totalAmount, taxAmount, netAmount, amountRemark);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.updateAmountInfo(invoiceId, totalAmount, taxAmount,
                netAmount, amountRemark) > 0;
        log.info("更新金额信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInvoiceInfo(Long invoiceId, String invoiceTitle, String taxpayerNumber,
                                    String invoiceAddress, String invoicePhone, String bankAccount) {
        log.info("更新开票信息，invoiceId={}, invoiceTitle={}, taxpayerNumber={}, invoiceAddress={}, invoicePhone={}, bankAccount={}",
                invoiceId, invoiceTitle, taxpayerNumber, invoiceAddress, invoicePhone, bankAccount);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.updateInvoiceInfo(invoiceId, invoiceTitle, taxpayerNumber,
                invoiceAddress, invoicePhone, bankAccount) > 0;
        log.info("更新开票信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateReceiptInfo(Long invoiceId, String recipientName, String recipientPhone,
                                   String recipientAddress, String deliveryMethod, String trackingNumber) {
        log.info("更新收票信息，invoiceId={}, recipientName={}, recipientPhone={}, recipientAddress={}, deliveryMethod={}, trackingNumber={}",
                invoiceId, recipientName, recipientPhone, recipientAddress, deliveryMethod, trackingNumber);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.updateReceiptInfo(invoiceId, recipientName, recipientPhone,
                recipientAddress, deliveryMethod, trackingNumber) > 0;
        log.info("更新收票信息完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateInvoiceStatus(List<Long> invoiceIds, Integer invoiceStatus) {
        log.info("批量更新发票状态，invoiceIds={}, invoiceStatus={}", invoiceIds, invoiceStatus);
        
        if (invoiceIds == null || invoiceIds.isEmpty() || invoiceStatus == null) {
            log.warn("发票ID列表和状态不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.batchUpdateInvoiceStatus(invoiceIds, invoiceStatus) > 0;
        log.info("批量更新发票状态完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateAuditStatus(List<Long> invoiceIds, Integer auditStatus) {
        log.info("批量更新审核状态，invoiceIds={}, auditStatus={}", invoiceIds, auditStatus);
        
        if (invoiceIds == null || invoiceIds.isEmpty() || auditStatus == null) {
            log.warn("发票ID列表和审核状态不能为空");
            return false;
        }
        
        boolean result = routeInvoiceMapper.batchUpdateAuditStatus(invoiceIds, auditStatus) > 0;
        log.info("批量更新审核状态完成，result={}", result);
        return result;
    }

    @Override
    public Map<String, Object> getRevenueStatistics(Long routeId, Long merchantId, LocalDateTime startTime,
                                                   LocalDateTime endTime, String statisticsType) {
        log.info("收入统计，routeId={}, merchantId={}, startTime={}, endTime={}, statisticsType={}",
                routeId, merchantId, startTime, endTime, statisticsType);
        
        Map<String, Object> result = routeInvoiceMapper.selectRevenueStatistics(routeId, merchantId,
                startTime, endTime, statisticsType);
        log.info("收入统计完成");
        return result;
    }

    @Override
    public Map<String, Object> getTaxStatistics(Long routeId, Long merchantId, LocalDateTime startTime,
                                               LocalDateTime endTime, String taxType) {
        log.info("税务统计，routeId={}, merchantId={}, startTime={}, endTime={}, taxType={}",
                routeId, merchantId, startTime, endTime, taxType);
        
        Map<String, Object> result = routeInvoiceMapper.selectTaxStatistics(routeId, merchantId,
                startTime, endTime, taxType);
        log.info("税务统计完成");
        return result;
    }

    @Override
    public Map<String, Object> checkInvoiceCompliance(Long invoiceId, Map<String, Object> complianceRules) {
        log.info("发票合规性检查，invoiceId={}, complianceRules={}", invoiceId, complianceRules);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return Map.of("success", false, "message", "发票ID不能为空");
        }
        
        Map<String, Object> result = routeInvoiceMapper.checkInvoiceCompliance(invoiceId, complianceRules);
        log.info("发票合规性检查完成");
        return result;
    }

    @Override
    public Map<String, Object> assessInvoiceRisk(Long invoiceId, Map<String, Object> riskFactors) {
        log.info("发票风险评估，invoiceId={}, riskFactors={}", invoiceId, riskFactors);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return Map.of("success", false, "message", "发票ID不能为空");
        }
        
        Map<String, Object> result = routeInvoiceMapper.assessInvoiceRisk(invoiceId, riskFactors);
        log.info("发票风险评估完成");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean softDeleteRouteInvoice(Long invoiceId) {
        log.info("软删除线路发票，invoiceId={}", invoiceId);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return false;
        }
        
        RouteInvoice routeInvoice = new RouteInvoice();
        routeInvoice.setId(invoiceId);
        routeInvoice.setDeleted(true);
        routeInvoice.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(routeInvoice);
        log.info("软删除线路发票完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchSoftDeleteRouteInvoices(List<Long> invoiceIds) {
        log.info("批量软删除线路发票，invoiceIds={}", invoiceIds);
        
        if (invoiceIds == null || invoiceIds.isEmpty()) {
            log.warn("发票ID列表不能为空");
            return false;
        }
        
        List<RouteInvoice> invoices = invoiceIds.stream()
                .map(id -> {
                    RouteInvoice invoice = new RouteInvoice();
                    invoice.setId(id);
                    invoice.setDeleted(true);
                    invoice.setUpdateTime(LocalDateTime.now());
                    return invoice;
                })
                .collect(Collectors.toList());
        
        boolean result = updateBatchById(invoices);
        log.info("批量软删除线路发票完成，result={}", result);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean restoreRouteInvoice(Long invoiceId) {
        log.info("恢复已删除的线路发票，invoiceId={}", invoiceId);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return false;
        }
        
        RouteInvoice routeInvoice = new RouteInvoice();
        routeInvoice.setId(invoiceId);
        routeInvoice.setDeleted(false);
        routeInvoice.setUpdateTime(LocalDateTime.now());
        
        boolean result = updateById(routeInvoice);
        log.info("恢复已删除的线路发票完成，result={}", result);
        return result;
    }

    @Override
    public List<Map<String, Object>> getRouteInvoiceOperationLogs(Long invoiceId, LocalDateTime startTime,
                                                                 LocalDateTime endTime, Integer limit) {
        log.info("查询线路发票操作日志，invoiceId={}, startTime={}, endTime={}, limit={}",
                invoiceId, startTime, endTime, limit);
        
        if (invoiceId == null) {
            log.warn("发票ID不能为空");
            return List.of();
        }
        
        List<Map<String, Object>> result = routeInvoiceMapper.selectRouteInvoiceOperationLogs(invoiceId, startTime, endTime, limit);
        log.info("查询线路发票操作日志完成，数量：{}", result.size());
        return result;
    }
}